#ifndef GODOT_VARIANT_HPP
#define GODOT_VARIANT_HPP

#include <stdio.h>
#include <cmath>
#include "gdnative_api_struct.gen.h"
#include <utility>
#if __SIZEOF_POINTER__== 4
#define POINTER_T int32_t
#elif __SIZEOF_POINTER__== 8
#define POINTER_T int64_t
#endif



namespace Godot
{

class String;


extern const godot_gdnative_core_api_struct *GODOT_CORE_API;
extern const godot_gdnative_core_1_1_api_struct *CORE_1_1_API;



class Variant:public godot_variant
{
public:
    Variant(void)
    {
        GODOT_CORE_API->godot_variant_new_nil(this);
    }
    Variant(bool b)
    {
        GODOT_CORE_API->godot_variant_new_bool(this,b);
    }
    Variant(int64_t i)
    {
        GODOT_CORE_API->godot_variant_new_int(this,i);
    }
    Variant(double i)
    {
        GODOT_CORE_API->godot_variant_new_real(this,i);
    }


    Variant(const Variant& p_v)
    {
        GODOT_CORE_API->godot_variant_new_copy(this,&p_v);
    }
    Variant& operator=(const Variant& p_v)
    {
        GODOT_CORE_API->godot_variant_destroy(this);//先将原本指向的数据清除
        GODOT_CORE_API->godot_variant_new_copy(this,&p_v);//拷贝数据
        return *this;
    }
    Variant(Variant&& p_v)
    {
        int i=3;//GODOT_VARIANT_SIZE/sizeof(int64_t)
        while(i--)
        {
            ((int64_t*)_dont_touch_that)[i]=((int64_t*)p_v._dont_touch_that)[i];
        };
    }
    Variant& operator=(Variant&& p_v)
    {
        GODOT_CORE_API->godot_variant_destroy(this);//先将原本指向的数据清除

        int i=3;//GODOT_VARIANT_SIZE/sizeof(int64_t)
        while(i--)
        {
            ((int64_t*)_dont_touch_that)[i]=((int64_t*)p_v._dont_touch_that)[i];
        };
        return *this;
    }
    ~Variant()
    {
       // printf(" ~Variant yes; \n");
        GODOT_CORE_API->godot_variant_destroy(this);//将原本指向的数据清除
    }

    template <typename T>
    T ValueOf(void)//RVO
    {

        return (T&&)(GODOT_CORE_API->*(T::VariantAs))(this);
    }
    template <typename T=void*>
    T ValueOfptr(void)
    {
        return (T&&)(((int64_t*)(_dont_touch_that))[1]);
    }

    inline void destroy();
    inline godot_variant_type get_type();

};
//inline func
void Variant::destroy()
{
    GODOT_CORE_API->godot_variant_destroy(this);
}
godot_variant_type Variant::get_type(){
 //printf("\n%d\n",GODOT_CORE_API->godot_variant_get_type(this));
    return GODOT_CORE_API->godot_variant_get_type(this);
}

};


#endif // GODOT_VARIANT_HPP

